<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src='lib/webgl-utils.js'></script>
    <script src='lib/webgl-debug.js'></script>
    <script src='lib/cuon-utils.js'></script>
    <script src="lib/cuon-matrix.js"></script>
</head>
<body onload="main()">
<canvas id="mybox" width="500" height="500">
    请更换新版浏览器查看效果!
</canvas>
<script >
//顶点   
//物体表面颜色a_color  
//物体表面法向量a_normal  
//模型的投影矩阵  
//光线颜色u_lightColor  
//光线方向u_lightDirection
//θ如果大于90度说明光线是照在物体表面的背面的
let VSHADER_SOURCE =`
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec4 a_normal;
uniform mat4 u_mvpMatrix;
uniform vec3 u_diffuseLight;
uniform vec3 u_ambientLight;
uniform vec3 u_lightDirection;
varying vec4 v_color;
void main(){
  gl_Position=u_mvpMatrix*a_position;
  vec3 normal=normalize(a_normal.xyz);
  float nDotL=max(dot(u_lightDirection,normal),0.0);
  vec3 diffuse=u_diffuseLight*a_color.rgb*nDotL;
  vec3 ambient=u_ambientLight*a_color.rgb;
  v_color=vec4(diffuse+ambient,a_color.a);
}
`

// Fragment shader program
let FSHADER_SOURCE =`
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_color;
void main(){
  gl_FragColor=v_color;
}
`
  

function main() {
  let canvas=document.getElementById('mybox');
  let gl=getWebGLContext(canvas);
  if(!gl){
    console.log('Failed to get the rendering context for WebGL');
    return;
  }
  if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){
    console.log('Failed to intialize shaders.');
    return;
  }
  let n=initVertexBuffers(gl);
  if(n<0){
    console.log('failed to initialize shaders.');
    return;
  }

  gl.clearColor(0,0,0,1);
  //开启隐藏面消除
  gl.enable(gl.DEPTH_TEST);
  let u_mvpMatrix=gl.getUniformLocation(gl.program,'u_mvpMatrix')
  let u_diffuseLight=gl.getUniformLocation(gl.program,'u_diffuseLight')
  let u_ambientLight=gl.getUniformLocation(gl.program,'u_ambientLight')
  let u_lightDirection=gl.getUniformLocation(gl.program,'u_lightDirection')
  if (!u_mvpMatrix || !u_diffuseLight || !u_lightDirection || !u_ambientLight) { 
    console.log('Failed to get the storage location');
    return;
  }
  gl.uniform3f(u_diffuseLight,1.0,1.0,1.0);
  
  //需要进行归一化处理
  let lightDirection=new Vector3([0.5,3.0,4.0]);
  lightDirection.normalize();
  gl.uniform3fv(u_lightDirection,lightDirection.elements);
  gl.uniform3f(u_ambientLight,0.2,0.2,0.2);

  let mvpMatrix=new Matrix4();
  mvpMatrix.setPerspective(30,canvas.width/canvas.height,1,100);
  mvpMatrix.lookAt(3,3,7,0,0,0,0,1,0)
  // false表示不对矩阵进行转置,webGL中必须指定为false
  gl.uniformMatrix4fv(u_mvpMatrix,false,mvpMatrix.elements);
  
  gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
  console.log(123)
  gl.drawElements(gl.TRIANGLES,n,gl.UNSIGNED_BYTE,0);
}

function initVertexBuffers(gl){
  let vertices=new Float32Array([
    1.0, 1.0, 1.0,  -1.0, 1.0, 1.0,  -1.0,-1.0, 1.0,   1.0,-1.0, 1.0, // v0-v1-v2-v3 front
     1.0, 1.0, 1.0,   1.0,-1.0, 1.0,   1.0,-1.0,-1.0,   1.0, 1.0,-1.0, // v0-v3-v4-v5 right
     1.0, 1.0, 1.0,   1.0, 1.0,-1.0,  -1.0, 1.0,-1.0,  -1.0, 1.0, 1.0, // v0-v5-v6-v1 up
    -1.0, 1.0, 1.0,  -1.0, 1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0,-1.0, 1.0, // v1-v6-v7-v2 left
    -1.0,-1.0,-1.0,   1.0,-1.0,-1.0,   1.0,-1.0, 1.0,  -1.0,-1.0, 1.0, // v7-v4-v3-v2 down
     1.0,-1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0, 1.0,-1.0,   1.0, 1.0,-1.0  // v4-v7-v6-v5 back
  ]);
  let colors=new Float32Array([
    1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,     // v0-v1-v2-v3 front
    1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,     // v0-v3-v4-v5 right
    1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,     // v0-v5-v6-v1 up
    1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,     // v1-v6-v7-v2 left
    1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,     // v7-v4-v3-v2 down
    1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0　    // v4-v7-v6-v5 back
  ]);
  let normals=new Float32Array([
    0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,  // v0-v1-v2-v3 front
    1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,  // v0-v3-v4-v5 right
    0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,  // v0-v5-v6-v1 up
   -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  // v1-v6-v7-v2 left
    0.0,-1.0, 0.0,   0.0,-1.0, 0.0,   0.0,-1.0, 0.0,   0.0,-1.0, 0.0,  // v7-v4-v3-v2 down
    0.0, 0.0,-1.0,   0.0, 0.0,-1.0,   0.0, 0.0,-1.0,   0.0, 0.0,-1.0   // v4-v7-v6-v5 back
  ]);
  let indices=new Uint8Array([
    0, 1, 2,   0, 2, 3,    // front
     4, 5, 6,   4, 6, 7,    // right
     8, 9,10,   8,10,11,    // up
    12,13,14,  12,14,15,    // left
    16,17,18,  16,18,19,    // down
    20,21,22,  20,22,23     // back
  ])
  if (!initArrayBuffer(gl, 'a_color', colors, 3, gl.FLOAT)) {
    return -1;
  }
  if (!initArrayBuffer(gl, 'a_normal', normals, 3, gl.FLOAT)) {
    return -1;
  }
  if (!initArrayBuffer(gl, 'a_position', vertices, 3, gl.FLOAT)) {
    return -1;
  }
  let indexBuffer=gl.createBuffer();
  if(!indexBuffer){
    console.log('Failed to create the buffer object');
    return false;
  }
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer);
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indices,gl.STATIC_DRAW);
 
  return indices.length
}

function initArrayBuffer(gl,attribute,data,num,type){
  var buffer=gl.createBuffer();
  if(!buffer){
    console.log('Failed to create the buffer object');
    return false;
  }
  gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
  gl.bufferData(gl.ARRAY_BUFFER,data,gl.STATIC_DRAW);

  var a_attribute=gl.getAttribLocation(gl.program,attribute);
  if (a_attribute < 0) {
    console.log('Failed to get the storage location of ' + attribute);
    return false;
  }
  gl.vertexAttribPointer(a_attribute,num,type,false,0,0)
  gl.enableVertexAttribArray(a_attribute);
  gl.bindBuffer(gl.ARRAY_BUFFER,null);
  return true;

}
</script>

</body>
</html>